/*
   Copyright (c) 2011, 2012, 2015 Mizar Tools Contributors (mizartools.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
/*  Contributors :
 *	2011-02-04 Marco Riccardi - initial implementation
 *	2011-03-20 Marco Riccardi - added the className "Symbols" in method createElement(File file, String className)
 *  2012-04-09 Marco Riccardi - added the className "ReductionRegistrations" in method createElement
 *  2015-01-11 Marco Riccardi - added the className "PropertyRegistration" in method createElement
 *  
 */
package org.mizartools.system;

import java.io.File;
import java.util.LinkedList;

import org.mizartools.system.xml.Constructors;
import org.mizartools.system.xml.Definientia;
import org.mizartools.system.xml.Environ;
import org.mizartools.system.xml.Formats;
import org.mizartools.system.xml.IdentifyRegistrations;
import org.mizartools.system.xml.Notations;
import org.mizartools.system.xml.PropertyRegistrations;
import org.mizartools.system.xml.ReductionRegistrations;
import org.mizartools.system.xml.Registrations;
import org.mizartools.system.xml.Requirements;
import org.mizartools.system.xml.Schemes;
import org.mizartools.system.xml.Symbols;
import org.mizartools.system.xml.Theorems;
import org.mizartools.system.xml.Vocabularies;
import org.mizartools.utility.xml.XMLElement;
import org.mizartools.utility.xml.XMLFile;

public class ElementFactory {

	private static ElementFactory elementFactory;
	private XMLFile xmlFile = new XMLFile();
	private ElementFactory(){}

	public static ElementFactory newInstance(){
		if (elementFactory == null) 
			elementFactory = new ElementFactory(); 
		return elementFactory;
	}
	
	public IElement createElement(File file) throws ElementParseException {
		synchronized (ElementFactory.class) {
			String extension = file.getName().substring(file.getName().length()-3, file.getName().length());
			String className = FileExtension.getClassName(extension);
			if (className == null) {
				throw new ElementParseException(ElementParseException.NOT_VALID_FILE_EXTENSION, "The file " + file.toString() + " has not a valid extension.");
			}
			IElement element = null;
			xmlFile.setFile(file);
			LinkedList<XMLElement> xmlElementList = xmlFile.getXMLElementList();
			if (xmlElementList.isEmpty()){
				throw new ElementParseException(ElementParseException.EMPTY_FILE, "The file " + file.toString() + " has not xml elements.");
			}
			if (className.equals("Constructors")){
				element = Constructors.newInstance(null, xmlElementList);
			} else if (className.equals("Notations")){
				element = Notations.newInstance(null, xmlElementList);
			} else if (className.equals("Requirements")){
				element = Requirements.newInstance(null, xmlElementList);
			} else if (className.equals("Definientia")){
				element = Definientia.newInstance(null, xmlElementList);
			} else if (className.equals("Schemes")){
				element = Schemes.newInstance(null, xmlElementList);
			} else if (className.equals("Theorems")){
				element = Theorems.newInstance(null, xmlElementList);
			} else if (className.equals("Registrations")){
				element = Registrations.newInstance(null, xmlElementList);
			} else if (className.equals("IdentifyRegistrations")){
				element = IdentifyRegistrations.newInstance(null, xmlElementList);
			} else if (className.equals("ReductionRegistrations")){
				element = ReductionRegistrations.newInstance(null, xmlElementList);
			}  else if (className.equals("PropertyRegistration")){
				element = PropertyRegistrations.newInstance(null, xmlElementList); // not error !! MML 5.22
			} 
			else
				throw new ElementParseException(ElementParseException.NOT_VALID_FILE_EXTENSION, "The file " + file.toString() + " has not a valid extension.");
			if (!xmlElementList.isEmpty()){
				throw new ElementParseException(ElementParseException.INCOMPLETE_PARSING, "The file " + file.toString() + " has xml elements not parsed.", xmlElementList);
			}
			return element;
		}
	}

	public IElement createElement(File file, String className) throws ElementParseException {
		synchronized (ElementFactory.class) {
			IElement element = null;
			xmlFile.setFile(file);
			LinkedList<XMLElement> xmlElementList = xmlFile.getXMLElementList();
			if (xmlElementList.isEmpty()){
				throw new ElementParseException(ElementParseException.EMPTY_FILE, "The file " + file.toString() + " has not xml elements.");
			}
			if (className.equals("Constructors")){
				element = Constructors.newInstance(null, xmlElementList);
			} else if (className.equals("Notations")){
				element = Notations.newInstance(null, xmlElementList);
			} else if (className.equals("Requirements")){
				element = Requirements.newInstance(null, xmlElementList);
			} else if (className.equals("Definientia")){
				element = Definientia.newInstance(null, xmlElementList);
			} else if (className.equals("Schemes")){
				element = Schemes.newInstance(null, xmlElementList);
			} else if (className.equals("Theorems")){
				element = Theorems.newInstance(null, xmlElementList);
			} else if (className.equals("Registrations")){
				element = Registrations.newInstance(null, xmlElementList);
			} else if (className.equals("IdentifyRegistrations")){
				element = IdentifyRegistrations.newInstance(null, xmlElementList);
			} else if (className.equals("Article")){
				element = org.mizartools.system.xml.Article.newInstance(null, xmlElementList);
			} else if (className.equals("Environ")){
				element = Environ.newInstance(null, xmlElementList);
			} else if (className.equals("Formats")){
				element = Formats.newInstance(null, xmlElementList);
			} else if (className.equals("Vocabularies")){
				element = Vocabularies.newInstance(null, xmlElementList);
			} else if (className.equals("Symbols")){
				element = Symbols.newInstance(null, xmlElementList);
			} 
			else
				throw new ElementParseException(ElementParseException.NOT_VALID_FILE_EXTENSION, "The file " + file.toString() + " has not a valid extension.");
			if (!xmlElementList.isEmpty()){
				throw new ElementParseException(ElementParseException.INCOMPLETE_PARSING, "The file " + file.toString() + " has xml elements not parsed.", xmlElementList);
			}
			return element;
		}
	}

}
